package MANA;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JPanel;


public class Board extends JPanel implements ActionListener {


	private static final long serialVersionUID = 1L;
	private ArrayList<Stairs> stairss = new ArrayList<Stairs>();
	private ArrayList<Wall> walls = new ArrayList<Wall>();
	private ArrayList<Floor> floors = new ArrayList<Floor>();
	private Level Level;
	

	private final int SPACE = 20;
	private int w = 0;
	private int h = 0;
	
    private final int LEFT_COLLISION = 1;
    private final int RIGHT_COLLISION = 2;
    private final int TOP_COLLISION = 3;
    private final int BOTTOM_COLLISION = 4;
	
	
	private String level;
	private Player player;
	
	public Board() {
		addKeyListener(new TAdapter());
		setBackground(Color.BLACK);
		setFocusable(true);
		initWorld();
	}
	
	public int getBoardWidth() {
		return this.w;
	}
	public int getBoardHeigth() {
		return this.h;
	}
	public void reloadLevel() {
		try {
			level = Level.setLevel("level" + player.getCurrentlvl() + ".txt");
		} catch(IOException ioe) {
			System.out.println("IOException:");
			ioe.printStackTrace();
			ioe.getMessage();
			level = "#####";
		} catch(Exception e) {
			e.getMessage();
			level = "#####";
		} finally {
			initWorld();
		}
	}
	public void initWorld() {
		int x = 0;
		int y = 0;
		Level = new Level();

		try {
			level = Level.setLevel("level0.txt");
		} catch(IOException e) {
			System.out.println("IOException:");
			System.out.println(e.getMessage());
			e.printStackTrace();
			level = "###";
		}
		
		Wall wall;
		Floor floor;
		Stairs stairs;
		for (int i = 0; i < level.length(); i++) {
			char item = level.charAt(i);
			
			if (item == '\n') {
				y += SPACE;
				if (this.w < x) {
					this.w = x;
				}
				
				x = 0;
			} else if (item == '#') {
				wall = new Wall(x, y);
				walls.add(wall);
				x += SPACE;
				
			} else if (item == '@') {
				if (player.getCurrentlvl() == player.getLastlvl()) {
					player = new Player(x, y);
					floor = new Floor(x, y);
					floors.add(floor);
					x += SPACE;
				}
			} else if (item == ' ') {
				floor = new Floor(x, y);
				floors.add(floor);
				x += SPACE;
			} else if (item == '<') {
				if (player.getCurrentlvl() < player.getLastlvl()) {
					player = new Player(x, y);
				}
				floor = new Floor(x, y);
				floors.add(floor);
				stairs = new Stairs(x, y, true);
				stairss.add(stairs);
				x += SPACE;
			} else if (item == '>') {
				if (player.getCurrentlvl() < player.getLastlvl()) {
					player = new Player(x, y);
				}
				floor = new Floor(x, y);
				floors.add(floor);
				stairs = new Stairs(x, y, false);
				stairss.add(stairs);
				x += SPACE;
				
			} else if (item == '+') {
				x += SPACE;
			}
			h = y;

		 }
	  }
	public void buildWorld(Graphics g) {

	        ArrayList<Actor> world = new ArrayList<Actor>();
	        world.addAll(walls);
	        world.addAll(floors);
	        world.addAll(stairss);
	        world.add(player);


	        for (int i = 0; i < world.size(); i++) {
	            Actor item = world.get(i);
	                g.drawImage(item.getImage(), item.x(), item.y(), this);
	        }
	}

	@Override
	public void paint(Graphics g) {
	     super.paint(g);
	     buildWorld(g);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		repaint();
	}
	
	class TAdapter extends KeyAdapter {
		
		@Override
		public void keyPressed(KeyEvent e) {
			int key = e.getKeyCode();
			if (key == KeyEvent.VK_SPACE){
				if (checkOnStairs(player)) {
					reloadLevel();
				} else {
					return;
				}
			}
			if (key == KeyEvent.VK_LEFT) {
                if (checkWallCollision(player,
                        LEFT_COLLISION)) {
                    return;
                }//if

                player.move(-SPACE, 0);
                
		     } else if (key == KeyEvent.VK_RIGHT) {
				if (checkWallCollision(player, RIGHT_COLLISION)) {
					return;
				}
				player.move(SPACE, 0);
		     } else if (key == KeyEvent.VK_UP) {
		    	 if (checkWallCollision(player, TOP_COLLISION)) {
		    		 return;
		    	 }
		    	 player.move(0, -SPACE);
		    	  
		     } else if (key == KeyEvent.VK_DOWN) {
		    	 if (checkWallCollision(player, BOTTOM_COLLISION)) {
		    		 return;
		    	 }
		    	 player.move(0, SPACE);
		     }
			 repaint();
		}

		private boolean checkOnStairs(Player player) {
	    	for (int i = 0; i < stairss.size(); i++) {
	    		Stairs stairs = stairss.get(i);
	    		if (player.isOnStairs(stairs)) {
	    			if (stairs.isStairsDown()) {
	    				player.decreaseLvl();
	    			} else {
	    				player.increaseLvl();
	    			}
	    			reloadLevel();
	    			return true;
	    		}
	    	}
	    	return false;
	    }
		private boolean checkWallCollision(Actor actor, int type) {
		        if (type == LEFT_COLLISION) {
		            for (int i = 0; i < walls.size(); i++) {
		                Wall wall = walls.get(i);
		                if (actor.isLeftCollision(wall)) {
		                    return true;
		                }
		            }
		            return false;

		        } else if (type == RIGHT_COLLISION) {

		            for (int i = 0; i < walls.size(); i++) {
		                Wall wall = walls.get(i);
		                if (actor.isRightCollision(wall)) {
		                    return true;
		                }
		            }
		            return false;

		        } else if (type == TOP_COLLISION) {

		            for (int i = 0; i < walls.size(); i++) {
		                Wall wall = walls.get(i);
		                if (actor.isTopCollision(wall)) {
		                    return true;
		                }
		            }
		            return false;

		        } else if (type == BOTTOM_COLLISION) {

		            for (int i = 0; i < walls.size(); i++) {
		                Wall wall = walls.get(i);
		                if (actor.isBottomCollision(wall)) {
		                    return true;
		                }
		            }
		            return false;
		        }
		        return false;
		}
	
	}
}
